home *** CD-ROM | disk | FTP | other *** search
-
- /*----------------------------------------------------------------------------+
- | |
- | comment.c |
- | |
- | This is code for an FKEY to do various commenting functions for C code. |
- | It takes text on the clipboard (or on the TEScrap), operates on it, |
- | and replaces it. |
- | |
- | If the option key is pressed within KEYDELAY ticks after the FKEY is |
- | called, the clipboard text will be commented with a line running down |
- | the left side, and the text indented with tabs. |
- | |
- | If the tab key is pressed within KEYDELAY ticks, the text will be |
- | surrounded with / * and * / characters, and any previously commented |
- | text will be replaced with SLASHREPLACEMENT (since commented comments |
- | aren't allowed in C). |
- | |
- | If the accent ("`") key is pressed with KEYDELAY ticks, the text |
- | will be assumed to have been previously commented, and any surrounding |
- | comment marks will be removed and any temporarily uncommented lines |
- | will be commented back in. It is the inverse of the previous |
- | operation. |
- | |
- | If no key is pressed within KEYDELAY ticks, the text will be surrounded |
- | in a large box, like this one. |
- | |
- | This FKEY does not (yet) work with programs that keep a private |
- | scrap (such as Word). How can I easily trick those programs into |
- | putting their scrap on the clipboard? |
- | |
- | This code and FKEY is free, but may not be resold and is copyrighted |
- | 1990 by David S. Fry. |
- | |
- | David Fry |
- | 81 Irving Street |
- | Cambridge, MA 02138 |
- | INTERNET: fry@math.harvard.edu |
- | April 22, 1990 |
- | |
- +----------------------------------------------------------------------------*/
-
- /* my own version of isspace() */
- #define isspace(x) (( (x) <= ' ' ) ? TRUE : FALSE)
-
- #define TABSPACE 4 /* spaces for tab in editor */
- #define LEFTCHAR '|' /* left char on box */
- #define RIGHTCHAR '|' /* right char on box */
- #define LINELEN 78 /* length of line */
- #define TOPCHAR '-' /* top of box */
- #define BOTCHAR '-' /* bottom of box */
- #define CORNERCHAR '+' /* corner of box */
- #define SIDECHAR '*' /* left side char */
- #define SLASHREPLACEMENT '|' /* what to replace "/" with */
-
- #define NULL 0L
-
- /* how many ticks to wait for user to press option, tab, or accent */
- #define KEYDELAY 45
-
- /* key codes */
- #define option_kc 58
- #define tab_kc 48
- #define accent_kc 50
-
- /*----------------------------------------------------------------------------+
- | Add text from little buffer to the big output buffer. |
- +----------------------------------------------------------------------------*/
-
- Ptr AddToOutText(textBuf,addBuf,len)
- Ptr textBuf,addBuf;
- long len;
- /*
- * This function takes text from the temporary buffer addBuff and
- * adds it to the text buffer textBuf.
- *
- * If there's a problem, it kills textBuf and returns NULL.
- */
- {
- long outSize;
- Ptr temp;
-
- outSize = GetPtrSize(textBuf);
- SetPtrSize(textBuf,outSize+len);
- if ( MemError() != noErr ) {
- /* hit a nonreloc block */
- temp = NewPtr((long)(outSize+len));
- if ( temp == NULL ) {
- DisposPtr(textBuf);
- return(NULL);
- }
- BlockMove(textBuf,temp,outSize);
- DisposPtr(textBuf);
- textBuf = temp;
- }
-
- BlockMove(addBuf,textBuf+outSize,len);
- return(textBuf);
- }
-
- /*----------------------------------------------------------------------------+
- | Check for key presses. |
- +----------------------------------------------------------------------------*/
-
- Boolean CheckKeyCode(kc)
- char kc;
- /*
- * Checks to see if the key with kc key code is down
- */
- {
- KeyMap theKeys;
-
- GetKeys(&theKeys);
- return( BitTst(&theKeys,
- (long) ((kc/8)*8 + 7 - (kc%8) ) ));
- }
-
- /*----------------------------------------------------------------------------+
- | Comment out (and in) large sections. |
- | Called if the tab key or "`" key is pressed. |
- +----------------------------------------------------------------------------*/
-
- Ptr CommentOut(inH,inSize,addcmts)
- Handle inH;
- long inSize;
- Boolean addcmts;
- /*
- * returns pointer to text
- */
- {
- long y;
- char *inT, *endT;
- char *outT;
- char buf[10];
- long beginning, ending;
- char *temp;
-
- inT = *inH;
- endT = inT + inSize;
- outT = NewPtr(0L);
-
- if ( addcmts ) {
-
- /*
- * We will comment out the whole section, and replace
- * any existing comments.
- */
-
- y = 0;
- buf[y++] = '/';
- buf[y++] = '*';
- buf[y++] = '\r';
- outT = AddToOutText(outT,buf,y);
- if ( outT == NULL )
- return(NULL);
-
- while ( inT < endT ) {
- if ( *inT == '/' &&
- (*(inT + 1) == '*' || *(inT-1) == '*') )
- *inT = SLASHREPLACEMENT;
- inT++;
- }
- inT = *inH;
- outT = AddToOutText(outT,inT,inSize);
- if ( outT == NULL )
- return(NULL);
-
- y = 0;
- buf[y++] = '*';
- buf[y++] = '/';
- buf[y++] = '\r';
- outT = AddToOutText(outT,buf,y);
-
- } else {
-
- /*
- * We will remove any surrounding comments (ignoring
- * text outside the first level of commenting) and
- * fix any previously replaced comments.
- */
-
- while ( inT < endT &&
- !(*inT == '/' && *(inT+1) == '*') ) {
- inT++;
- }
- if ( inT < endT )
- inT += 2;
- if ( inT < endT && *inT == '\r' )
- inT++;
- beginning = inT - *inH;
- if ( beginning == inSize )
- beginning = 0;
-
- inT = endT-1;
- temp = *inH + beginning;
- while ( inT > temp &&
- !(*inT == '*' && *(inT+1) == '/') ) {
- inT--;
- }
- ending = endT - inT;
- if ( ending == inSize )
- ending = 0;
-
- inT = *inH + beginning;
- endT = *inH + inSize - ending;
-
- while ( inT < endT ) {
- if ( *inT == SLASHREPLACEMENT &&
- ( *(inT+1) == '*' || *(inT-1) == '*') )
- *inT = '/';
- inT++;
- }
-
- inT = *inH + beginning;
- outT = AddToOutText(outT,inT,inSize - beginning - ending);
- }
-
- return(outT);
- }
-
- /*----------------------------------------------------------------------------+
- | Add comments on the left side of text. |
- | Called when the option key is pressed. |
- +----------------------------------------------------------------------------*/
-
- Ptr SideNote(inH,inSize)
- Handle inH;
- long inSize;
- /*
- * returns pointer to text
- */
- {
- long y;
- char *inT, *endT;
- char *outT;
- char buf[256];
- char firstpart[50];
- long firstlen;
- long actualcnt;
- long firstactual;
-
- inT = *inH;
- endT = inT + inSize;
-
- firstlen = 0; firstactual = 0;
- while ( inT < endT ) {
- if ( *inT == '\r' ) {
- /* end of line...start over */
- *inT++;
- firstlen = 0;
- firstactual = 0;
- continue;
- }
- if ( isspace(*inT) ) {
- firstpart[firstlen] = *inT;
- firstlen++;
- inT++;
- if ( *inT == '\t' )
- firstactual = ((firstactual + TABSPACE)/TABSPACE)*TABSPACE;
- else
- firstactual++;
- } else
- /* we've run out of white space */
- break;
- }
- inT = *inH;
-
- outT = NewPtr(0L);
-
- /* now we put in the first line */
- y = 0;
- while ( y < firstlen ) {
- buf[y] = firstpart[y];
- y++;
- }
- buf[y++] = '/';
- buf[y++] = '*';
- buf[y++] = '\r';
-
- outT = AddToOutText(outT,buf,y);
- if ( outT == NULL )
- return(NULL);
-
-
- do {
-
- /*
- * First we need to remove the beginning part of the the line
- * so everything lines up properly.
- */
- actualcnt = 0;
- while ( actualcnt < firstactual
- && inT < endT && *inT != '\r' ) {
- if ( *inT == '\t' )
- actualcnt = ((actualcnt+TABSPACE)/TABSPACE)*TABSPACE;
- else
- actualcnt++;
- inT++;
- }
-
-
- if ( *inT == '/' && *(inT+1) == '*' ) {
- /* skip this line */
- while ( inT < endT && *inT != '\r' ) { inT++; }
- if ( inT < endT )
- inT++;
- continue;
- }
-
- if ( (*inT == '*' && *(inT+1) == '/') ||
- (*inT == '/' && *(inT-1) == '*') ) {
- /* skip this line */
- while ( inT < endT && *inT != '\r' ) { inT++; }
- if ( inT < endT )
- inT++;
- continue;
- }
-
- if ( *inT == SIDECHAR ) {
- inT++;
- if ( *inT == '\t' )
- inT++;
- }
-
- y = 0;
- while ( y < firstlen ) {
- buf[y] = firstpart[y];
- y++;
- }
- buf[y++] = SIDECHAR;
- buf[y++] = '\t';
-
- while ( inT < endT && *inT != '\r' ) {
- buf[y++] = *inT;
- inT++;
- }
-
- if ( *inT == '\r' ) {
- buf[y++] = '\r';
- inT++;
- }
-
- outT = AddToOutText(outT,buf,(long)y);
- if ( outT == NULL )
- return(NULL);
-
- } while ( inT < endT );
-
- /* now put in last line */
- y = 0;
- while ( y < firstlen ) {
- buf[y] = firstpart[y];
- y++;
- }
- buf[y++] = '*';
- buf[y++] = '/';
- buf[y++] = '\r';
-
- outT = AddToOutText(outT,buf,(long)y);
-
- return(outT);
- }
-
- /*----------------------------------------------------------------------------+
- | Surround the text with a big box like this. |
- | Called when no key is presed for KEYDELAY Ticks. |
- +----------------------------------------------------------------------------*/
-
- Ptr BigBox(inH,inSize)
- Handle inH;
- long inSize;
- /*
- * returns pointer to text
- */
- {
- long x,y;
- char *inT, *endT;
- char *outT;
- char buf[256];
- Boolean firstChar;
- short actualcnt;
-
- inT = *inH;
- endT = inT + inSize;
-
- outT = NewPtr(0L);
-
- /* put in first line */
- y = 0;
- buf[y++] = '/';
- buf[y++] = '*';
- for ( x = 0; x < LINELEN - 2; x++ )
- buf[y++] = TOPCHAR;
- buf[y++] = CORNERCHAR;
- buf[y++] = '\r';
-
- outT = AddToOutText(outT,buf,(long)y);
-
- if ( outT == NULL )
- return(NULL);
-
- inT = *inH;
- do {
-
- if ( *inT == '/' && *(inT+1) == '*' && *(inT+2) == TOPCHAR ) {
- /* skip this line */
- while ( inT < endT && *inT != '\r' ) { inT++; }
- if ( inT < endT )
- inT++;
- continue;
- }
-
- if ( *inT == CORNERCHAR && *(inT+1) == BOTCHAR && *(inT+2) == BOTCHAR ) {
- /* skip this line */
- while ( inT < endT && *inT != '\r' ) { inT++; }
- if ( inT < endT )
- inT++;
- continue;
- }
-
- firstChar = TRUE;
- y = 0;
- actualcnt = 0;
- buf[y++] = LEFTCHAR;
- actualcnt++;
- while ( inT < endT && *inT != '\r' ) {
-
- if ( firstChar ) {
- firstChar = FALSE;
- if ( *inT == LEFTCHAR ) {
- inT++;
- continue;
- }
- }
-
- buf[y++] = *inT;
-
- if ( *inT == '\t' )
- /* tab */
- actualcnt = ((actualcnt+TABSPACE)/TABSPACE)*TABSPACE;
- else
- actualcnt++;
-
- inT++;
-
- }
-
- if ( *inT == '\r' ) {
- if ( *(inT-1) != RIGHTCHAR || y < 2 ) {
-
- /* pad with spaces */
- while ( actualcnt < LINELEN ) {
- buf[y++] = ' ';
- actualcnt++;
- }
- buf[y++] = RIGHTCHAR;
-
- }
- buf[y++] = '\r';
- inT++;
- }
-
- outT = AddToOutText(outT,buf,(long)y);
- if ( outT == NULL )
- return(NULL);
-
- } while ( inT < endT );
-
-
- /* now put bottom line */
- y = 0;
- buf[y++] = CORNERCHAR;
- for ( x = 0; x < LINELEN - 2; x++ )
- buf[y++] = BOTCHAR;
- buf[y++] = '*';
- buf[y++] = '/';
- buf[y++] = '\r';
-
- outT = AddToOutText(outT,buf,(long)y);
-
- return(outT);
- }
-
-
-
- /*----------------------------------------------------------------------------+
- | Main function. |
- +----------------------------------------------------------------------------*/
-
- main()
- {
- Handle inH;
- long inSize;
- long offset;
- Boolean useTEScrap = FALSE;
- long time;
- Boolean opt = FALSE, tab = FALSE, accent = FALSE;
- Ptr outT;
-
- time = TickCount();
- do {
- opt = CheckKeyCode(option_kc);
- tab = CheckKeyCode(tab_kc);
- accent = CheckKeyCode(accent_kc);
- } while ( TickCount() - time < KEYDELAY &&
- !(opt || tab || accent) );
-
- if ( opt || tab || accent )
- FlushEvents(keyDownMask+keyUpMask+autoKeyMask,0);
-
- if ( TEGetScrapLen() > 0 ) {
- useTEScrap = TRUE;
- ZeroScrap();
- TEToScrap();
- }
-
- inH = NewHandle(0L);
- inSize = GetScrap(inH,'TEXT',&offset);
-
- if ( inSize < 0 ) {
- /* no text there */
- DisposHandle(inH);
- SysBeep(30);
- return;
- }
-
- MoveHHi(inH);
- HLock(inH);
-
- if ( opt )
- outT = SideNote(inH,inSize);
- else if ( tab )
- outT = CommentOut(inH,inSize,TRUE);
- else if ( accent )
- outT = CommentOut(inH,inSize,FALSE);
- else
- outT = BigBox(inH,inSize);
-
- HUnlock(inH);
- DisposHandle(inH);
-
- if ( outT == NULL ) {
- SysBeep(30);
- return;
- }
-
- ZeroScrap();
- PutScrap(GetPtrSize(outT),'TEXT',outT);
-
- if ( useTEScrap )
- TEFromScrap();
-
- DisposPtr(outT);
- return;
- }
-
-